package com.baofu.paycore.service.converter;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.baofu.clear.service.facade.model.resp.NotifyDTO;
import com.baofu.paycore.biz.model.BackPayBO;
import com.baofu.paycore.biz.model.PayResBO;
import com.baofu.paycore.biz.model.WebPayBO;
import com.baofu.paycore.dal.model.*;
import com.baofu.paycore.manager.model.PayBO;
import com.baofu.paycore.manager.model.PayBaseBO;
import com.baofu.paycore.manager.model.RefundBO;
import com.baofu.paycore.manager.model.SubPayBO;
import com.baofu.paycore.service.facade.model.*;
import com.baofu.paycore.service.facade.model.AccountFreeze.FreezeResDTO;
import com.baofu.paycore.service.facade.model.authconfirm.AuthConfirmResDTO;
import com.baofu.paycore.service.facade.model.authorize.AuthorizeResDTO;
import com.baofu.paycore.service.facade.model.pay.FundDetailInfoRespDTO;
import com.baofu.paycore.service.facade.model.pay.PayQueryDetailRespDTO;
import com.baofu.paycore.service.facade.model.recharge.RechargeAccountRespDTO;
import com.baofu.paycore.service.facade.model.recharge.RechargeBankRespDTO;
import com.baofu.paycore.service.facade.model.recharge.RechargeQueryResDTO;
import com.baofu.paycore.service.facade.model.recharge.RechargeResDTO;
import com.baofu.paycore.service.facade.model.transfer.TransferResDTO;
import com.baofu.paycore.service.facade.model.transfer.UnfreezeTransferResDTO;
import com.baofu.paycore.service.facade.model.withdraw.WithdrawResDTO;
import com.google.common.collect.Lists;
import com.system.commons.utils.BeanCopyUtil;

import java.util.Date;
import java.util.List;

/**
 * BO转换成DTO对象
 * <p>
 *     1、充值接口返回结果信息处理
 * </p>
 * User: kwl  Date: 16/5/6 ProjectName: paycore Version: 5.0.0
 */
public class BO2DTOConverter {

    /**
     * 页面跳转URL对象BO转DTO WebPayBO to WebPayResDTO
     *
     * @param webPayBO        充值结果
     * @return   WebPayResDTO
     */
    public static WebPayResDTO getWebPayResDTO(WebPayBO webPayBO,PayBaseBO domainModel){

        WebPayResDTO webPayResDTO = new WebPayResDTO();
        if(null == webPayBO){
            return webPayResDTO;
        }
        webPayResDTO.setRealRtnFlag(webPayBO.isRealFlag());
        webPayResDTO.setRequestDate(domainModel.getRequestDate());
        webPayResDTO.setRequestBizNo(domainModel.getRequestBizNo());
        webPayResDTO.setRequestOrderNo(domainModel.getRequestOrderNo());
        webPayResDTO.setErrorCode(webPayBO.getErrorCode());
        webPayResDTO.setErrorMsg(webPayBO.getErrorMsg());
        webPayResDTO.setStatus(webPayBO.getStatus());
        webPayResDTO.setOutPayUrl(webPayBO.getOutPayUrl());
        webPayResDTO.setPaymentInfo(webPayBO.getPaymentInfo());
        webPayResDTO.setPayNo(webPayBO.getPayNo());
        webPayResDTO.setParams(webPayBO.getParams());
        return webPayResDTO;
    }

    /**
     * 页面跳转URL对象BO转DTO WebPayBO to WebPayResDTO
     *
     * @param backPayBO       充值结果
     * @return   WebPayResDTO
     */
    public static RechargeResDTO getRechargeResDTO(BackPayBO backPayBO){

        RechargeResDTO rechargeResDTO = new RechargeResDTO();
        if(null == backPayBO){
            return rechargeResDTO;
        }
        rechargeResDTO.setPayNo(backPayBO.getPayNo());
        rechargeResDTO.setRealRtnFlag(backPayBO.isRealFlag());
        rechargeResDTO.setCcy(backPayBO.getCcy());
        rechargeResDTO.setAmt(backPayBO.getAmt());
        rechargeResDTO.setBankCode(backPayBO.getBankCode());
        rechargeResDTO.setBankName(backPayBO.getBankName());
        rechargeResDTO.setRequestOrderNo(backPayBO.getRequestOrderNo());
        rechargeResDTO.setRespDate(backPayBO.getPayDate());
        rechargeResDTO.setPaymentInfo(backPayBO.getPaymentInfo());
        getRechargeResDTO(backPayBO,rechargeResDTO);
        return rechargeResDTO;
    }

    /**
     * 支付返回结果基类DTO转换
     *
     * @param backPayBO        充值结果
     * @param payBaseResDTO    支付返回结果基类DTO
     */
    private static void getRechargeResDTO(BackPayBO backPayBO, PayBaseResDTO payBaseResDTO){
        payBaseResDTO.setRequestBizNo(backPayBO.getRequestBizNo());
        payBaseResDTO.setRequestDate(backPayBO.getRequestDate());
        payBaseResDTO.setErrorCode(backPayBO.getErrorCode());
        payBaseResDTO.setErrorMsg(backPayBO.getErrorMsg());
        payBaseResDTO.setStatus(backPayBO.getStatus());
    }

    /**
     * 页面跳转URL对象BO转DTO WebPayBO to WebPayResDTO
     *
     * @param backPayBO       充值结果
     * @return   WebPayResDTO
     */
    public static PayResDTO getConsumeResDTO(PayResDTO payResDTO, BackPayBO backPayBO){

        if(null == backPayBO){
            return payResDTO;
        }
        payResDTO.setRequestOrderNo(backPayBO.getRequestOrderNo());
        payResDTO.setPayNo(backPayBO.getPayNo());
        payResDTO.setCcy(backPayBO.getCcy());
        payResDTO.setAmt(backPayBO.getAmt());
        payResDTO.setRealRtnFlag(backPayBO.isRealFlag());
        payResDTO.setRespDate(backPayBO.getPayDate());
        payResDTO.setBankName(backPayBO.getBankName());
        payResDTO.setBankCode(backPayBO.getBankCode());
        payResDTO.setPaymentInfo(backPayBO.getPaymentInfo());
        getRechargeResDTO(backPayBO, payResDTO);
        return payResDTO;
    }

    /**
     * 转账
     *
     */
    public static TransferResDTO getTransferResDTO(BackPayBO backPayBO){
        TransferResDTO payResDTO = new TransferResDTO();
        getConsumeResDTO(payResDTO,backPayBO);
        return payResDTO;
    }

    /**
     * 转账
     *
     */
    public static UnfreezeTransferResDTO getUnfreezeTransferResDTO(BackPayBO backPayBO){
        UnfreezeTransferResDTO payResDTO = new UnfreezeTransferResDTO();
        getConsumeResDTO(payResDTO,backPayBO);
        return payResDTO;
    }

    /**
     * 转账撤销
     *
     */
    public static CancelResDTO getCancelTransferResDTO(BackPayBO backPayBO){
        CancelResDTO payResDTO = new CancelResDTO();
        getConsumeResDTO(payResDTO,backPayBO);
        return payResDTO;
    }

    /**
     * 转换预授权响应对象
     *
     * @param backPayBO     返回对象
     * @return              AuthorizeResDTO
     */
    public static AuthorizeResDTO getAuthorizeResDTO(BackPayBO backPayBO){
        AuthorizeResDTO authorizeResDTO = new AuthorizeResDTO();
        if (backPayBO == null){
            return null;
        }
        authorizeResDTO.setRequestOrderNo(backPayBO.getRequestOrderNo());
        authorizeResDTO.setPayNo(backPayBO.getPayNo());
        authorizeResDTO.setCcy(backPayBO.getCcy());
        authorizeResDTO.setAmt(backPayBO.getAmt());
        authorizeResDTO.setPreAuthIssueAmt(backPayBO.getAmt());
        authorizeResDTO.setRealRtnFlag(backPayBO.isRealFlag());
        authorizeResDTO.setRespDate(backPayBO.getPayDate());
        authorizeResDTO.setBankName(backPayBO.getBankName());
        authorizeResDTO.setBankCode(backPayBO.getBankCode());
        authorizeResDTO.setPaymentInfo(backPayBO.getPaymentInfo());
        authorizeResDTO.setFreezeCode(backPayBO.getFreezeCode());
        getRechargeResDTO(backPayBO, authorizeResDTO);

        return authorizeResDTO;
    }

    /**
     * 转换预授权确认响应对象
     *
     * @param backPayBO     返回对象
     * @return              AuthorizeResDTO
     */
    public static AuthConfirmResDTO getAuthorizeConfirmResDTO(BackPayBO backPayBO){
        AuthConfirmResDTO authConfirmResDTO = new AuthConfirmResDTO();
        if (backPayBO == null){
            return null;
        }
        authConfirmResDTO.setRequestOrderNo(backPayBO.getRequestOrderNo());
        authConfirmResDTO.setPayNo(backPayBO.getPayNo());
        authConfirmResDTO.setCcy(backPayBO.getCcy());
        authConfirmResDTO.setAmt(backPayBO.getAmt());
        authConfirmResDTO.setRealRtnFlag(backPayBO.isRealFlag());
        authConfirmResDTO.setRespDate(backPayBO.getPayDate());
        authConfirmResDTO.setBankName(backPayBO.getBankName());
        authConfirmResDTO.setBankCode(backPayBO.getBankCode());
        authConfirmResDTO.setPaymentInfo(backPayBO.getPaymentInfo());
        getRechargeResDTO(backPayBO, authConfirmResDTO);

        return authConfirmResDTO;
    }

    /**
     * 返回预授权撤销响应对象
     *
     * @param backPayBO     返回对象
     * @return              CancelResDTO
     */
    public static CancelResDTO getAuthorizeCancelResDTO(BackPayBO backPayBO){
        CancelResDTO cancelResDTO = new CancelResDTO();
        if (backPayBO == null){
            return null;
        }
        cancelResDTO.setRequestOrderNo(backPayBO.getRequestOrderNo());
        cancelResDTO.setPayNo(backPayBO.getPayNo());
        cancelResDTO.setCcy(backPayBO.getCcy());
        cancelResDTO.setAmt(backPayBO.getAmt());
        cancelResDTO.setRealRtnFlag(backPayBO.isRealFlag());
        cancelResDTO.setRespDate(backPayBO.getPayDate());
        getRechargeResDTO(backPayBO, cancelResDTO);

        return cancelResDTO;
    }

    /**
     * 获取转账响应信息
     *
     * @param backPayBO     银行返回对象
     * @return              WithdrawResDTO
     */
    public static WithdrawResDTO getWithdrawResDTO(BackPayBO backPayBO){
        WithdrawResDTO withdrawResDTO = new WithdrawResDTO();
        if (null == backPayBO){
            return withdrawResDTO;
        }
        withdrawResDTO.setBankName(backPayBO.getBankName());
        withdrawResDTO.setBankCode(backPayBO.getBankCode());
        withdrawResDTO.setCcy(backPayBO.getCcy());
        withdrawResDTO.setAmt(backPayBO.getAmt());
        withdrawResDTO.setErrorCode(backPayBO.getErrorCode());
        withdrawResDTO.setErrorMsg(backPayBO.getErrorMsg());
        withdrawResDTO.setPayNo(backPayBO.getPayNo());
        withdrawResDTO.setRealRtnFlag(backPayBO.isRealFlag());
        withdrawResDTO.setRequestBizNo(backPayBO.getRequestBizNo());
        withdrawResDTO.setRequestOrderNo(backPayBO.getRequestOrderNo());
        withdrawResDTO.setRequestDate(backPayBO.getRequestDate());
        withdrawResDTO.setRespDate(backPayBO.getResponseDate());
        withdrawResDTO.setStatus(backPayBO.getStatus());
        return withdrawResDTO;
    }

    /**
     * 获取退款响应信息
     *
     * @param payResBO     退款返回结果BO
     * @return             退款返回结果DTO
     */
    public static PayResDTO getRefundResDTOByPayResBO(PayResBO payResBO){

        PayResDTO payResDTO = new PayResDTO();
        if (null == payResBO){
            return payResDTO;
        }
        payResDTO.setRequestOrderNo(payResBO.getRequestOrderNo());
        payResDTO.setRequestBizNo(payResBO.getRequestBizNo());
        payResDTO.setRequestDate(payResBO.getRequestDate());
        payResDTO.setErrorCode(payResBO.getErrorCode());
        payResDTO.setErrorMsg(payResBO.getErrorMsg());
        payResDTO.setStatus(payResBO.getStatus());

        payResDTO.setPayNo(payResBO.getPayNo());
        payResDTO.setCcy(payResBO.getCcy());
        payResDTO.setAmt(payResBO.getAmt());
        payResDTO.setRealRtnFlag(payResBO.isRealFlag());
        payResDTO.setRespDate(new Date());
        payResDTO.setBankCode(payResBO.getBankCode());
        payResDTO.setBankName(payResBO.getBankName());
        return payResDTO;
    }

    /**
     * 获取退款幂等性响应信息
     *
     * @param refundBO     退款返回结果BO
     * @return             退款返回结果DTO
     */
    public static PayResDTO getRefundResDTOByRefundBO(RefundBO refundBO){

        PayResDTO payResDTO = new PayResDTO();
        if (null == refundBO){
            return payResDTO;
        }
        payResDTO.setRequestOrderNo(refundBO.getRequestOrderNo());
        payResDTO.setRequestBizNo(refundBO.getRequestBizNo());
        payResDTO.setRequestDate(refundBO.getRequestDate());
        payResDTO.setErrorCode(refundBO.getErrorCode());
        payResDTO.setErrorMsg(refundBO.getErrorMsg());
        payResDTO.setStatus(refundBO.getStatus());

        payResDTO.setPayNo(refundBO.getPayNo());
        payResDTO.setCcy(refundBO.getCcy());
        payResDTO.setAmt(refundBO.getAmt());
        payResDTO.setRealRtnFlag(true);
        payResDTO.setRespDate(new Date());
        return payResDTO;
    }

    /**
     * 获取支付消息信息
     *
     * @param payBaseBO     支付信息
     * @param callBackDTO   回调信息
     * @return              支付消息信息
     */
    public static PayMessageDTO getPayMessageDTO(PayBaseBO payBaseBO, NotifyDTO callBackDTO) {

        if (payBaseBO == null) {
            return null;
        }
        PayMessageDTO payMessageDTO = new PayMessageDTO();
        payMessageDTO.setPayNo(payBaseBO.getPayNo());
        payMessageDTO.setStatus(payBaseBO.getStatus());
        payMessageDTO.setRequestSystem(payBaseBO.getRequestSystem());
        payMessageDTO.setRequestBizNo(payBaseBO.getRequestBizNo());
        payMessageDTO.setRequestOrderNo(payBaseBO.getRequestOrderNo());
        payMessageDTO.setAmt(payBaseBO.getAmt());
        payMessageDTO.setErrorCode(payBaseBO.getErrorCode());
        payMessageDTO.setErrorMsg(payBaseBO.getErrorMsg());
        payMessageDTO.setRespDate(new Date());
        payMessageDTO.setDescription(payBaseBO.getDescription());
        payMessageDTO.setTradeLogId(payBaseBO.getTradeLogId());
        payMessageDTO.setAgreeRelId(callBackDTO.getAgreeRelId());
        payMessageDTO.setPaymentInfo(payBaseBO.getPaymentInfo());
        payMessageDTO.setTradeLogId(callBackDTO.getTradeLogId());

        return payMessageDTO;
    }

    /**
     * 参数转换
     *
     * @param transferDO    转账对象
     * @return              PayResDTO
     */
    public static PayResDTO transferToPayResDTO(TransferDO transferDO){
        PayResDTO payResDTO = new PayResDTO();
        payResDTO.setAmt(transferDO.getAmt().longValue());
        payResDTO.setCcy(transferDO.getCcy());
        payResDTO.setPayNo(transferDO.getPayNo());
        payResDTO.setRespDate(new Date());
        payResDTO.setStatus(transferDO.getStatus());
        payResDTO.setRequestBizNo(transferDO.getRequestBizNo());
        payResDTO.setRequestOrderNo(transferDO.getRequestOrderNo());
        payResDTO.setRequestDate(transferDO.getRequestDate());

        return payResDTO;
    }

    /**
     * 参数转换
     *
     * @param preAuthDO    转账对象
     * @return              PayResDTO
     */
    public static PayResDTO preAuthToPayResDTO(PreAuthDO preAuthDO){
        PayResDTO payResDTO = new PayResDTO();
        payResDTO.setAmt(preAuthDO.getAmt().longValue());
        payResDTO.setCcy(preAuthDO.getCcy());
        payResDTO.setPayNo(preAuthDO.getPayNo());
        payResDTO.setRespDate(new Date());
        payResDTO.setStatus(preAuthDO.getStatus());
        payResDTO.setRequestBizNo(preAuthDO.getRequestBizNo());
        payResDTO.setRequestOrderNo(preAuthDO.getRequestOrderNo());
        payResDTO.setRequestDate(preAuthDO.getRequestDate());

        return payResDTO;
    }

    /**
     * 参数转换
     *
     * @param freezeDO    冻结对象
     * @return              PayResDTO
     */
    public static PayResDTO freezeToPayResDTO(FreezeDO freezeDO){
        PayResDTO payResDTO = new PayResDTO();
        payResDTO.setCcy(freezeDO.getCcy());
        payResDTO.setAmt(freezeDO.getAmt().longValue());
        payResDTO.setPayNo(freezeDO.getPayNo());
        payResDTO.setRespDate(new Date());
        payResDTO.setStatus(freezeDO.getStatus());
        payResDTO.setErrorCode(freezeDO.getErrorCode());
        payResDTO.setErrorMsg(freezeDO.getErrorReason());
        payResDTO.setRequestBizNo(freezeDO.getRequestBizNo());
        payResDTO.setRequestOrderNo(freezeDO.getRequestOrderNo());
        payResDTO.setRequestDate(freezeDO.getRequestDate());

        return payResDTO;
    }
    /**
     * 对象转换响应对象
     *
     * @param lists     集合
     * @return          List<PayQueryRespDTO>
     */
    public static List<PayQueryRespDTO> getPayResDTOByPayDO(List<PayDO> lists){

        List<PayQueryRespDTO> list = Lists.newArrayList();
        if (CollectionUtils.isEmpty(lists)){
            return list;
        }
        lists.forEach(payDO -> {
            PayQueryRespDTO payResDTO = buildPayResDTO(payDO.getRequestOrderNo(), payDO.getRequestBizNo(),
                    payDO.getRelationNo(), payDO.getRequestSystem(), payDO.getRequestChannel(), payDO.getRequestDate(),
                    payDO.getPayNo(), payDO.getStatus(), payDO.getCcy(), payDO.getAmt(),null);
            list.add(payResDTO);
        });

        return list;
    }

    /**
     * 对象转换响应对象
     *
     * @param lists     集合
     * @return          List<PayQueryRespDTO>
     */
    public static List<PayQueryRespDTO> getPayResDTOByClearDO(List<ClearDO> lists){

        List<PayQueryRespDTO> list = Lists.newArrayList();
        if (CollectionUtils.isEmpty(lists)){
            return list;
        }
        lists.forEach(clearDO -> {
            PayQueryRespDTO payResDTO = buildPayResDTO(clearDO.getRequestOrderNo(), clearDO.getRequestBizNo(),
                    clearDO.getRelationNo(), clearDO.getRequestSystem(), clearDO.getRequestChannel(),
                    clearDO.getRequestDate(), clearDO.getPayNo(), clearDO.getStatus(), clearDO.getCcy(),
                    clearDO.getAmt(),clearDO.getServiceCode());
            list.add(payResDTO);
        });

        return list;
    }

    /**
     * 对象转换响应对象
     *
     * @param lists     集合
     * @return          List<PayQueryRespDTO>
     */
    public static List<PayQueryRespDTO> getPayResDTOByTransferDO(List<TransferDO> lists){

        List<PayQueryRespDTO> list = Lists.newArrayList();
        if (CollectionUtils.isEmpty(lists)){
            return list;
        }
        lists.forEach(transferDO -> {
            PayQueryRespDTO payResDTO = buildPayResDTO(transferDO.getRequestOrderNo(), transferDO.getRequestBizNo(),
                    transferDO.getRelationNo(), transferDO.getRequestSystem(), transferDO.getRequestChannel(),
                    transferDO.getRequestDate(), transferDO.getPayNo(), transferDO.getStatus(), transferDO.getCcy(),
                    transferDO.getAmt().longValue(),transferDO.getServiceCode());
            list.add(payResDTO);
        });

        return list;
    }

    private static PayQueryRespDTO buildPayResDTO(String requestOrderNo, String requestBizNo, String relationNo,
                                            String requestSystem, String requestChannel, Date requestDate, String payNo,
                                            String status, String ccy, long amt,String serviceCode){
        PayQueryRespDTO payResDTO = new PayQueryRespDTO();
        payResDTO.setCcy(ccy);
        payResDTO.setAmt(amt);
        payResDTO.setPayNo(payNo);
        payResDTO.setStatus(status);
        payResDTO.setRelationNo(relationNo);
        payResDTO.setRequestDate(requestDate);
        payResDTO.setRequestBizNo(requestBizNo);
        payResDTO.setRequestOrderNo(requestOrderNo);
        payResDTO.setRequestSystem(requestSystem);
        payResDTO.setRequestChannel(requestChannel);
        payResDTO.setServiceCode(serviceCode);

        return payResDTO;
    }

    public static FundDetailInfoRespDTO getFundDetailInfoRespDTO(SubPayBO subPayBO, ClearDO clearDO, ClearBankDO clearBankDO,
                                                           List<ClearAccountDO> clearAccountDOs){
        FundDetailInfoRespDTO fundDetailInfoRespDTO = BeanCopyUtil.objConvert(subPayBO, FundDetailInfoRespDTO.class);
        RechargeQueryResDTO rechargeQueryResDTO = new RechargeQueryResDTO();
        if (clearDO != null){
            BeanCopyUtil.copy(clearDO, rechargeQueryResDTO);
        }
        if (clearBankDO != null){
            rechargeQueryResDTO.setRechargeBankRespDTO(BeanCopyUtil.objConvert(clearBankDO, RechargeBankRespDTO.class));
        }
        if (CollectionUtils.isNotEmpty(clearAccountDOs)){
            rechargeQueryResDTO.setRechargeAccountRespDTOs(BeanCopyUtil.convertList(clearAccountDOs,
                    RechargeAccountRespDTO.class));
        }
        fundDetailInfoRespDTO.setRechargeQueryResDTO(rechargeQueryResDTO);

        return fundDetailInfoRespDTO;
    }

    /**
     * 获取转账响应信息
     *
     * @param backPayBO     银行返回对象
     * @return              WithdrawResDTO
     */
    public static FreezeResDTO getFreezeResDTO(BackPayBO backPayBO){
        FreezeResDTO freezeResDTO = new FreezeResDTO();
        if (null == backPayBO){
            return freezeResDTO;
        }
        freezeResDTO.setBankName(backPayBO.getBankName());
        freezeResDTO.setBankCode(backPayBO.getBankCode());
        freezeResDTO.setCcy(backPayBO.getCcy());
        freezeResDTO.setAmt(backPayBO.getAmt());
        freezeResDTO.setErrorCode(backPayBO.getErrorCode());
        freezeResDTO.setErrorMsg(backPayBO.getErrorMsg());
        freezeResDTO.setPayNo(backPayBO.getPayNo());
        freezeResDTO.setRealRtnFlag(backPayBO.isRealFlag());
        freezeResDTO.setRequestBizNo(backPayBO.getRequestBizNo());
        freezeResDTO.setRequestOrderNo(backPayBO.getRequestOrderNo());
        freezeResDTO.setRequestDate(backPayBO.getRequestDate());
        freezeResDTO.setRespDate(backPayBO.getResponseDate());
        freezeResDTO.setStatus(backPayBO.getStatus());
        freezeResDTO.setFreezeCode(backPayBO.getFreezeCode());
        return freezeResDTO;
    }
}
